package xin.petstore.framework.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.zip.GZIPInputStream;


public class RequestUtil {

	/**
	 * sendGetRequest:发送GET请求<br/>
	 *
	 * @author lijing
	 * @param url  URL
	 * @param proxy  代理 
	 * @param executionTime  超时时间
	 * @param charset  编码
	 * @return
	 */
	public static String sendGetRequest(final String url, final Proxy proxy, long executionTime, final String charset) {

		final ExecutorService exec = Executors.newFixedThreadPool(1);
		Callable<String> call = new Callable<String>() {

			public String call() throws Exception {
				// 耗时操作代码块
				return sendGetRequest(url, "", "", 0, proxy, charset);
			}
		};
		String content = "";
		try {
			Future<String> future = exec.submit(call);
			content = future.get(executionTime, TimeUnit.MILLISECONDS);
		} catch (TimeoutException ex) {
			return "";
		} catch (Exception e) {
			return "";
		}
		exec.shutdown(); // 关闭线程池

		try {
			return new String(content.toString().getBytes(), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			return "";
		}

	}

	/**
	 * sendGetRequest:发送GET请求 <br/>
	 *
	 * @author lijing
	 * @param url   URL
	 * @param proxy  代理 
	 * @param cookie  cookie
	 * @param executionTime  超时时间
	 * @param charset  编码 
	 * @return
	 */
	public static String sendGetRequest(final String url, final Proxy proxy, final String cookie, long executionTime,
			final String charset) {

		final ExecutorService exec = Executors.newFixedThreadPool(1);
		Callable<String> call = new Callable<String>() {

			public String call() throws Exception {
				// 耗时操作代码块
				return sendGetRequest(url, "", cookie, 0, proxy, charset);
			}
		};
		String content = "";
		try {
			Future<String> future = exec.submit(call);
			content = future.get(executionTime, TimeUnit.MILLISECONDS);
		} catch (TimeoutException ex) {
			return "";
		} catch (Exception e) {
			return "";
		}
		exec.shutdown(); // 关闭线程池

		try {

			return new String(content.toString().getBytes(), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			return "";
		}

	}

	/**
	 * sendGetRequest:发送GET请求<br/>
	 *
	 * @author lijing
	 * @param url  url
	 * @param proxy  代理 
	 * @param executionTime  执行时间
 	 * @param retries  重试次数
	 * @param charset  编码
	 * @return
	 */
	public static String sendGetRequest(String url, Proxy proxy, long executionTime, int retries, String charset) {
		String content = "";
		int _retries = 0;
		while (content.isEmpty() && _retries < retries) {
			_retries++;
			content = sendGetRequest(url, proxy, executionTime, charset);
		}
		if (content.isEmpty()) {
			return "";
		}
		try {

			return new String(content.toString().getBytes(), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			return "";
		}
	}

	/**
	 * sendGetRequest:发送get请求 <br/>
	 * 
	 * @author lijing
	 * @param url
	 *          url参数
	 * @param executionTime
	 *          执行时间
	 * @param retries
	 *          重试次数
	 * @param charset
	 *          编码格式
	 * @return 页面返回内容
	 */
	public static String sendGetRequest(String url, long executionTime, int retries, String charset) {
		String content = "";
		int _retries = 0;
		while (content.isEmpty() && _retries < retries) {
			_retries++;
			content = sendGetRequest(url, null, executionTime, charset);
		}
		if (content.isEmpty()) {
			return "";
		}
		try {

			return new String(content.toString().getBytes(), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			return "";
		}
	}

	/**
	 * sendGetRequest:发送GET请求 <br/>
	 *
	 * @author lijing
	 * @param url  URL
	 * @param param  参数
	 * @param cookie 	COOKIE
	 * @param connectionTime 连接时间
	 * @param proxy  代理 
	 * @param charset 编码 
	 * @return
	 */
	public static String sendGetRequest(String url, String param, String cookie, int connectionTime, Proxy proxy,
			String charset) {

		String content = "";
		BufferedReader buffReader = null;

		try {
			String requestUrl = "";
			// 验证param是否为空，是否需要拼接param
			if (param.isEmpty()) {
				requestUrl = url;
			} else {
				requestUrl = url + "?" + param;
			}
			URL realUrl = new URL(requestUrl);

			// 使用代理，打开和URL之间的连接
			URLConnection connection;
			if (proxy == null) {
				connection = realUrl.openConnection();
			} else {
				connection = realUrl.openConnection(proxy);
			}

			// 设置通用的请求属性
			connection.setRequestProperty("accept", "*/*");
			connection.setRequestProperty("connection", "Keep-Alive");
			// 添加Cookie
			if (!cookie.isEmpty()) {
				connection.setRequestProperty("cookie", cookie);

			}

			// 设置可以输出
			connection.setDoOutput(true);
			// 设置可以读取默认是true
			connection.setDoInput(true);
			// 设置所有的http连接自动处理重定向
			HttpURLConnection.setFollowRedirects(true);
			// 设置本次连接自动处理重定向
			((HttpURLConnection) connection).setInstanceFollowRedirects(true);
			// 设置不适用缓存，因为我们的数据是实时更新的
			connection.setUseCaches(false);

			// 设置http连接时间
			if (connectionTime != 0) {
				connection.setConnectTimeout(connectionTime);
			}
			// 建立实际的连接
			connection.connect();
			connection.getHeaderFields();
			int responseCode = ((HttpURLConnection) connection).getResponseCode();
			if (responseCode == 200) {
				buffReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
				String line;
				while ((line = buffReader.readLine()) != null) {
					content += line + "\n";
				}
			} else {
				String urls = connection.getHeaderField("Location");
				return urls;
			}
		} catch (Exception e) {
		}
		// 使用finally块来关闭输入流
		finally {
			try {
				if (buffReader != null) {
					buffReader.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
		try {
			return new String(content.toString().getBytes(), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			return "";
		}
	}

	/**
	 * sendGetRequest:发送GET请求<br/>
	 *
	 * @author lijing
	 * @param url  URL
	 * @param param 参数
	 * @param headers 头信息
	 * @param connectionTime  连接时间
	 * @param proxy  代理
	 * @param charset  编码
	 * @return
	 */
	public static String sendGetRequest(String url, String param, Map<String, String> headers, int connectionTime,
			Proxy proxy, String charset) {

		StringBuffer content = new StringBuffer();
		BufferedReader buffReader = null;

		try {
			String requestUrl = "";
			// 验证param是否为空，是否需要拼接param
			if (param.isEmpty()) {
				requestUrl = url;
			} else {
				requestUrl = url + "?" + param;
			}

			URL realUrl = new URL(requestUrl);

			// 使用代理，打开和URL之间的连接
			URLConnection connection;
			if (proxy == null) {
				connection = realUrl.openConnection();
			} else {
				connection = realUrl.openConnection(proxy);
			}

			// 设置通用的请求属性
			connection.setRequestProperty("connection", "Keep-Alive");
			connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

			for (Iterator<String> i = headers.keySet().iterator(); i.hasNext();) {
				String key = i.next();
				String value = headers.get(key);
				connection.setRequestProperty(key, value);

			}

			// 设置可以输出
			connection.setDoOutput(true);
			// 设置可以读取默认是true
			connection.setDoInput(true);
			// 设置所有的http连接自动处理重定向
			// HttpURLConnection.setFollowRedirects(true);
			// 设置本次连接自动处理重定向
			// ((HttpURLConnection)
			// connection).setInstanceFollowRedirects(true);
			// 设置不适用缓存，因为我们的数据是实时更新的
			connection.setUseCaches(false);

			// 设置http连接时间
			if (connectionTime != 0) {
				connection.setConnectTimeout(connectionTime);
			}
			// 建立实际的连接
			connection.connect();
			connection.getHeaderFields();

			int responseCode = ((HttpURLConnection) connection).getResponseCode();
			if (responseCode == 200) {
				GZIPInputStream urlInputStream = new GZIPInputStream(connection.getInputStream());
				buffReader = new BufferedReader(new InputStreamReader(urlInputStream));
				String line;
				while ((line = buffReader.readLine()) != null) {
					content.append(line);
				}
			} else {
				String urls = connection.getHeaderField("Location");
				return urls;
			}
		} catch (Exception e) {
			System.out.println("失败");
		}
		// 使用finally块来关闭输入流
		finally {
			try {
				if (buffReader != null) {
					buffReader.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}

		// return content.toString();
		try {
			return new String(content.toString().getBytes("gbk"), "gbk");
		} catch (UnsupportedEncodingException e) {
			return "";
		}
	}

	/**
	 * sendGetRequest:发送GET请求<br/>
	 *
	 * @author lijing
	 * @param url URL
	 * @param param  参数
	 * @param proxy  代理
	 * @param connectionTime  连接时间
	 * @param charset 编码
	 * @return
	 */
	public static String sendGetRequest(String url, String param, Proxy proxy, int connectionTime, String charset) {

		StringBuffer content = new StringBuffer();
		BufferedReader buffReader = null;
		URLConnection connection;

		try {
			String requestUrl = "";
			// 验证param是否为空，是否需要拼接param
			if (param.isEmpty()) {
				requestUrl = url;
			} else {
				requestUrl = url + "?" + param;
			}
			URL realUrl = new URL(requestUrl);

			// 使用代理，打开和URL之间的连接
			if (proxy == null) {
				connection = realUrl.openConnection();
			} else {
				connection = realUrl.openConnection(proxy);
			}

			// 设置通用的请求属性
			connection.setRequestProperty("connection", "Keep-Alive");
			// 设置可以输出
			connection.setDoOutput(true);
			// 设置可以读取默认是true
			connection.setDoInput(true);
			// 设置所有的http连接自动处理重定向
			// HttpURLConnection.setFollowRedirects(true);
			// 设置本次连接自动处理重定向
			// ((HttpURLConnection)
			// connection).setInstanceFollowRedirects(true);
			// 设置不适用缓存，因为我们的数据是实时更新的
			connection.setUseCaches(false);

			// 设置http连接时间
			if (connectionTime != 0) {
				connection.setConnectTimeout(connectionTime);
			}
			// 建立实际的连接
			connection.connect();
			connection.getHeaderFields();

			int responseCode = ((HttpURLConnection) connection).getResponseCode();

			if (responseCode == 200) {

				buffReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), charset));
				String line;
				while ((line = buffReader.readLine()) != null) {
					content.append(line);
				}
			} else if (responseCode == 302) {
				String urls = connection.getHeaderField("Location");
				return urls;
			}

		} catch (Exception e) {
			System.out.println("失败");
		}
		// 使用finally块来关闭输入流
		finally {
			try {
				if (buffReader != null) {
					buffReader.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
		try {
			return new String(content.toString().getBytes("gbk"), "gbk");
		} catch (UnsupportedEncodingException e) {
			return "";
		}
	}

	/**
	 * sendPostRequest:发送POST请求 <br/>
	 *
	 * @author lijing
	 * @param url  URL
	 * @param param 参数
	 * @param cookie cookie
	 * @param retries 重试次数 
	 * @param charset 编码 
	 * @return
	 */
	public static String sendPostRequest(String url, String param, String cookie, int retries, String charset) {
		String content = "";
		int _retries = 0;
		while (content.isEmpty() && _retries < retries) {

			content = sendPostRequest(url, param, cookie, 10000, null, charset);
		}
		if (content.isEmpty()) {
		}
		try {

			return new String(content.toString().getBytes(), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			return "";
		}
	}

	/**
	 * sendPostRequest:发送POST请求 <br/>
	 *
	 * @author lijing
	 * @param url  URL
	 * @param param 参数
	 * @param cookie COOKIE
	 * @param connectionTime  连接时间
	 * @param proxy  代理
	 * @param charset 编码
	 * @return
	 */
	public static String sendPostRequest(String url, String param, String cookie, int connectionTime, Proxy proxy,
			String charset) {
		PrintWriter out = null;
		BufferedReader buffReader = null;
		String content = "";
		try {
			URL realUrl = new URL(url);
			// 打开和URL之间的连接
			URLConnection connection;
			// 使用代理，打开和URL之间的连接
			if (proxy == null) {
				connection = realUrl.openConnection();
			} else {
				connection = realUrl.openConnection(proxy);
			}
			// 设置通用的请求属性
			connection.setRequestProperty("accept", "*/*");
			connection.setRequestProperty("connection", "Keep-Alive");
			connection.setRequestProperty("user-agent",
					"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)");
			if(cookie!=null){
				connection.setRequestProperty("Cookie", cookie);
			}
			connection
					.setRequestProperty(
							"Referer",
							"http://list.taobao.com/itemlist/nvzhuang2011a.htm?cat=16&viewIndex=1&as=0&spm=5221.539771.5825413.3&atype=b&style=grid&same_info=1&isnew=2&tid=0&_input_charset=utf-8");
			connection.setConnectTimeout(connectionTime);

			// 发送POST请求必须设置如下两行
			connection.setDoOutput(true);
			connection.setDoInput(true);
			// 获取URLConnection对象对应的输出流
			out = new PrintWriter(connection.getOutputStream());
			// 发送请求参数
			if(param!=null){
				out.print(param);
			}
			// flush输出流的缓冲
			out.flush();
			// 定义BufferedReader输入流来读取URL的响应
			buffReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), charset));
			String line;
			while ((line = buffReader.readLine()) != null) {
				content += line + "\n";
			}
		} catch (Exception e) {
			System.out.println("发送 POST 请求出现异常！" + e);
			e.printStackTrace();
		}
		// 使用finally块来关闭输出流、输入流
		finally {
			try {
				if (out != null) {
					out.close();
				}
				if (buffReader != null) {
					buffReader.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		try {

			return new String(content.toString().getBytes(), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			return "";
		}
	}
	public static String sendPostRequest(String url,String param, int executionTime,
			int retries, String charset) {
		return sendPostRequest( url,param,null,null,executionTime,retries,charset);
	}
	/**
	 * sendPostRequest:发送POST请求. <br/>
	 *
	 * @author lijing
	 * @param url  URL
	 * @param param 参数
	 * @param cookie COOKIE
	 * @param proxy  代理
	 * @param executionTime  执行时间
	 * @param retries  重试次数 
	 * @param charset  编码
	 * @return
	 */
	public static String sendPostRequest(String url, String param, String cookie, Proxy proxy, int executionTime,
			int retries, String charset) {
		String content = "";
		int _retries = 0;
		while (content.isEmpty() && _retries < retries) {

			if (proxy != null) {
				content = sendPostRequest(url, param, cookie, executionTime, proxy, charset);
			} else {
				content = sendPostRequest(url, param, cookie, executionTime, null,charset);
			}
			_retries++;
		}
		if (content.isEmpty()) {
			return "";
		}
		try {

			return new String(content.toString().getBytes(), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			return "";
		}
	}

	/**
	 * sendPostRequest:发送POST请求 <br/>
	 *
	 * @author lijing
	 * @param url
	 * @param param
	 * @param cookie
	 * @param proxy
	 * @param executionTime
	 * @param charset
	 * @return
	 */
	public static String sendPostRequest(final String url, final String param, final String cookie, final Proxy proxy,
			long executionTime, final String charset) {
		final ExecutorService exec = Executors.newFixedThreadPool(1);
		Callable<String> call = new Callable<String>() {

			public String call() throws Exception {
				// 耗时操作代码块
				return sendPostRequest(url, param, cookie, 0, proxy, charset);
			}
		};
		String content = "";
		try {
			Future<String> future = exec.submit(call);
			content = future.get(executionTime, TimeUnit.MILLISECONDS);
		} catch (TimeoutException ex) {
			return "";
		} catch (Exception e) {
			return "";
		}
		exec.shutdown(); // 关闭线程池
		try {

			return new String(content.toString().getBytes(), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			return "";
		}
	}

}
